1. Field of the Invention
This invention is related to computer systems and, more particularly, to interrupt handling mechanisms within computer systems.
2. Description of the Relevant Art
Modern computer systems and the software which runs thereon demand a high performance interrupt structure in order to operate efficiently. Interrupts are used to switch between tasks, and so a multi-tasking operating system benefits from a high performance interrupt structure. A "multi-tasking" operating system is configured to run multiple programs concurrently. Additionally, interrupts provide a means for an electronic device external to the microprocessor to request attention from the operating system. Modern day computer systems are including increasing numbers of these electronic devices, prompting the need for a high performance interrupt structure.
Interrupts cause a microprocessor within the computer system to suspend execution of a task and to execute a specific software routine (referred to as an interrupt service routine) comprising a set of instructions. The interrupt is typically unrelated to the instructions being executed by the microprocessor at the time the interrupt occurs. Instead, the interrupt is caused by an external device requiring software attention. For example, a buffer within an input/output device may fill with data to be transferred to another device or to memory. Many other sources for interrupts are well-known to the skilled artisan.
The instructions being executed by the microprocessor at the time the interrupt occurs are referred to herein as a "task". A task may be a portion of a program, an operating system routine, or even another interrupt service routine.
Because the interrupt is normally unrelated to the task being performed by the microprocessor and is asynchronous to the task itself, the interrupt service routine is executed in such a way that the task may be resumed. In order to resume the task, the "context" within which the task is executing is saved to memory. The context includes register values associated with the task when the task is interrupted. Additionally, the context may include the values within any memory locations that may be accessible to the task. The register portion of the context is saved to memory, and the memory locations are saved by causing the current values stored therein to be visible to the computer system. For example, memory locations are saved if stored into a data cache and the data cache is maintained coherent with main memory. After saving the context, the interrupt service routine is executed. Upon completion of the interrupt service routine, the context is restored to the microprocessor and the task is resumed. Since the restored context is identical to the context when the task was interrupted, the task executes normally. In other words, the interrupt had no effect on the result of executing the task. Instead, only the time required to execute the task is affected.
The x86 architecture defines the context of 32 bit microprocessors to be 68 bytes. Additionally, when the segment registers (which are part of the context in the x86 architecture) are reloaded, segment reloads are initiated to translate the segments. More bytes are transferred when the reload occurs, and clock cycles are required to translate the extra bytes into a format for storing within the microprocessor.
Unfortunately, storing a large number of bytes to memory (as a context save entails) often requires a relatively large number of clock cycles. A clock cycle refers to the amount of time required by portions of the microprocessor to perform their functions. The results of each function are stored in a storage location (e.g. a register or memory) according to a clock signal defining the clock cycle and may be used by another function in the next clock cycle. The bus used by a microprocessor to communicate with other electrical devices may operate according to a different clock cycle than the microprocessor itself. The clock cycle associated with the bus is often referred to as the bus clock cycle.
If the context is saved by the microprocessor when an interrupt is recognized by the microprocessor, the interrupt is being handled via a "task switch". Task switches may also be used to switch between tasks which are not interrupt service routines. When handled via a task switch, the interrupt service routine is isolated from the interrupted task such that any modifications the interrupt service routine performs to the microprocessor's context information may not affect the operation of the task when resumed. The context is restored prior to resuming the task.
Often, an interrupt service routine will only require access to a few registers within the register set to perform its function. In this case, a full context save is not necessary since some registers will not be modified by the interrupt service routine. Instead, only those storage locations which must be changed in order to fetch the instructions within the interrupt service routine need be saved prior to beginning execution of the interrupt service routine. For example, in the x86 architecture the EIP register and CS segment register (which define the address and segment of the instructions to be fetched and executed) and the flags register (which is modified by many of the x86 instructions) are saved. These values are pushed onto the stack defined by the x86 architecture, when the task switch method of interrupt handling is not being used.
When the task switch method of interrupt handling is not in use, an interrupt service routine saves the values stored within registers which it employs to carry out its intended function. Often, the values are stored on the stack. This method of interrupt handling is referred to as an interrupt gate or trap gate in the x86 architecture, depending on whether or not the interrupt service routine may itself be interrupted. If the interrupt service routine does not use all of the microprocessor's context, then clock cycles may be saved with respect to performing the full context save of a task switch. The interrupt service routine is entered and exited more rapidly since context save and restore is not performed. Unfortunately, at least a few registers may still be stored.
Since there are multiple sources of interrupts, the computer system provides a mechanism for identifying one of multiple interrupt service routines. The computer system thus provides flexibility to the programmer in that a particular interrupt service routine may be tailored to the needs of a particular device. If no such mechanism were provided, all interrupts would fetch an interrupt service routine from the same address in memory. A relatively complicated routine stored at the address would need to be written to perform the handling of all types of interrupts from all electronic devices. As used herein, the term "fetching" refers to transferring the contents of a memory location to a destination.
One method for providing the address of the interrupt service routine for a given interrupt is for the microprocessor to request an interrupt vector from another electronic device in the system. An "interrupt vector" is a number which is indicative of a particular interrupt service routine. In the x86 microprocessor, for example, the interrupt vector is an index into an interrupt descriptor table which provides information identifying the address of the associated interrupt service routine.
In many computer systems, the interrupt vector is provided via a dedicated bus transaction. A "bus transaction" is a transfer of information across a bus. Bus transactions may include address and data information as well as the type of transfer. Bus transactions may be address-only, in which an address and related control information are broadcast; data-only, in which data and related control information are broadcast; or address-data in which both address and data are involved. As referred to herein, a bus transaction dedicated for interrupt processing is an interrupt acknowledge bus transaction. Typically, an interrupt acknowledge bus transaction is performed by the microprocessor to acknowledge the existence of an interrupt condition and then a second interrupt acknowledge bus transaction is performed to collect the interrupt vector. Unfortunately, many clock cycles are used to perform the two interrupt acknowledge bus transactions. Until the interrupt vector is known, the computer system may not begin fetching the interrupt service routine (since the interrupt service routine's address is not known). It would be desirable to collect the interrupt vector rapidly, so as to increase the performance of the computer system by entering the interrupt service routine more rapidly without losing the flexibility which having the interrupt vector allows.